import * as THREE from 'three'
import createThreeApp from '../../core'

function createCircleGeometry (dom: HTMLElement) {
  const { camera, scene, update, gui } = createThreeApp(dom)
  // 设置相机位置，不设置会在(0, 0, 0)位置
  camera.position.set(-30, 40, 35)
  camera.lookAt(scene.position)
  // 添加一个环境光
  const ambient = new THREE.AmbientLight(0xffffff, 1)
  scene.add(ambient)
  // 添加一个坐标轴
  const axesHelper = new THREE.AxesHelper(50)
  scene.add(axesHelper)

  // 创建一个网格
  const gridHelper = new THREE.GridHelper(50, 10)
  scene.add(gridHelper)

  // 创建一个平面
  const plane = new THREE.PlaneGeometry(60, 60)
  const planeMaterial = new THREE.MeshLambertMaterial({ color: 0xffffff })
  const planeMesh = new THREE.Mesh(plane, planeMaterial)
  planeMesh.rotateX(-Math.PI / 2)
  planeMesh.position.y = -0.1
  scene.add(planeMesh)

  // 创建一个圆
  const mesh = createCircleFromGeometry()
  mesh.position.set(30, 15, 0)
  scene.add(mesh)

  // 创建一个圆
  const bufferMesh = createCircleFromBufferGeometry()
  scene.add(bufferMesh)
  bufferMesh.position.set(-30, 15, 0)
  scene.add(bufferMesh)

  // 设置网格对象的动画效果
  update((time: number) => {
    mesh.rotation.x = time / 2000
    mesh.rotation.y = time / 1000

    bufferMesh.rotation.x = time / 2000
    bufferMesh.rotation.y = time / 1000
  })

  function updateMeshs () {
    generateGeometry(mesh)
    generateGeometry(bufferMesh)
  }

  gui.add(data, 'radius', 0, 30).onChange(updateMeshs)
  gui.add(data, 'segments', 1, 30, 1).onChange(updateMeshs)
  gui.add(data, 'thetaStart', 0, Math.PI * 2).onChange(updateMeshs)
  gui.add(data, 'thetaLength', 0, Math.PI * 2).onChange(updateMeshs)
}

const data = {
  radius: 10,
  segments: 10,
  thetaStart: 0,
  thetaLength: Math.PI * 2
}

function createCircleFromGeometry () {
  const { radius, segments, thetaStart, thetaLength } = data
  const geometry = new THREE.CircleGeometry(radius, segments, thetaStart, thetaLength)
  const material = new THREE.MeshNormalMaterial({ side: THREE.DoubleSide, wireframe: true })
  const meth = new THREE.Mesh(geometry, material)
  return meth
}

function createCircleFromBufferGeometry () {
  const { radius, segments, thetaStart, thetaLength } = data
  const geometry = new THREE.CircleBufferGeometry(radius, segments, thetaStart, thetaLength)
  const material = new THREE.MeshNormalMaterial({ side: THREE.DoubleSide })
  const mesh = new THREE.Mesh(geometry, material)
  return mesh
}

function generateGeometry (mesh: THREE.Mesh) {
  const { radius, segments, thetaStart, thetaLength } = data
  const geometry = new THREE.CircleBufferGeometry(radius, segments, thetaStart, thetaLength)
  mesh.geometry.dispose()
  mesh.geometry = geometry
}

export {
  createCircleGeometry
}
